home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume3 / dnamail < prev    next >
Encoding:
Text File  |  1989-02-03  |  45.6 KB  |  1,651 lines

  1. Path: xanth!mcnc!gatech!bloom-beacon!husc6!necntc!ncoast!allbery
  2. From: darin@decwrl.dec.com@c.UUCP (Darin Johnson)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i012: SUN <-> DECNET mailer
  5. Message-ID: <236@laic.UUCP>
  6. Date: 8 May 88 21:04:37 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: darin@decwrl.dec.com@c.UUCP (Darin Johnson)
  9. Organization: Lockheed AI Center, Menlo Park
  10. Lines: 1638
  11. Approved: allbery@ncoast.UUCP
  12.  
  13. comp.sources.misc: Volume 3, Issue 12
  14. Submitted-By: "Darin Johnson" <darin@decwrl.dec.com@c.UUCP>
  15. Archive-Name: dnamail
  16.  
  17. This mailer handles decnet mail to/from a Sun running Sunlink/DNI.
  18.  
  19. I am posting this mailer to both comp.sys.sun and comp.sources.misc.
  20. The reason for both groups is that I used to have problems getting sources
  21. from the comp.sys.sun archives, and I assume other people still have
  22. this problem.
  23.  
  24. The following is a shar file, you should know what to do...
  25.  
  26. ================  Cut, fold, or mutilate here ========================
  27. #! /bin/sh
  28. # This is a shell archive, meaning:
  29. # 1. Remove everything above the #! /bin/sh line.
  30. # 2. Save the resulting text in a file.
  31. # 3. Execute the file with /bin/sh (not csh) to create the files:
  32. #    Makefile
  33. #    README
  34. #    dnamail.doc
  35. #    dnamail.h
  36. #    dnamail.c
  37. #    dnamaild.c
  38. #    dnamisc.c
  39. #    dnaerror.c
  40. #    main.diff
  41. #    sub.diff
  42. # This archive created: Sun May  8 13:56:04 1988
  43. export PATH; PATH=/bin:$PATH
  44. echo shar: extracting "'Makefile'" '(415 characters)'
  45. if test -f 'Makefile'
  46. then
  47.     echo shar: will not over-write existing file "'Makefile'"
  48. else
  49. cat << \SHAR_EOF > 'Makefile'
  50. #
  51. DISTRIB = Makefile README dnamail.doc dnamail.h dnamail.c dnamaild.c dnamisc.c \
  52.       dnaerror.c main.diff sub.diff
  53.  
  54. OBJS = dnaerror.o dnamisc.o
  55.  
  56. all: dnamail dnamaild
  57.  
  58. dnamail: dnamail.o $(OBJS)
  59.     cc -o dnamail dnamail.o $(OBJS)
  60.  
  61. dnamaild: dnamaild.o $(OBJS)
  62.     cc -o dnamaild dnamaild.o $(OBJS)
  63.  
  64. dnamail.o dnamaild.o dnamisc.o: dnamail.h
  65.  
  66. shar: $(DISTRIB)
  67.     shar -cv $(DISTRIB) > dnamail.shar
  68.  
  69. clean:
  70.     rm -f *.o core
  71. SHAR_EOF
  72. if test 415 -ne "`wc -c < 'Makefile'`"
  73. then
  74.     echo shar: error transmitting "'Makefile'" '(should have been 415 characters)'
  75. fi
  76. chmod +x 'Makefile'
  77. fi # end of overwriting check
  78. echo shar: extracting "'README'" '(877 characters)'
  79. if test -f 'README'
  80. then
  81.     echo shar: will not over-write existing file "'README'"
  82. else
  83. cat << \SHAR_EOF > 'README'
  84. OK, here is my mailer for use with Sunlink/DNI.  You may use this with
  85. or without sendmail, although using it with sendmail is much more convenient
  86. (although it requires changes to the sendmail configuration files.)
  87.  
  88. 1) Read dnamail.doc for instructions
  89.  
  90. 2)
  91.     The patch files should work with the default 'sendmail.cf' files
  92.     off of the Sun distribution tape.  If not, you can install the
  93.     patches by hand.  Be SURE to keep the ".orig" files around in
  94.     case of problems.
  95.  
  96. 4)
  97.     Let me know of any problems you have setting this up, or of any bugs.
  98.         This way I can either fix the code, or fix the documentation.
  99.  
  100.     Note the copyright restrictions (as small as they are).  Of course, 
  101.         if Sun is negotiable, I may let them have it ;-)
  102.  
  103. Darin Johnson 
  104. Lockheed Missiles & Space
  105.           (...lll-lcc.arpa!leadsv!laic!darin)
  106.           (...ucbvax!sun!sunncal!leadsv!laic!darin)
  107. SHAR_EOF
  108. if test 877 -ne "`wc -c < 'README'`"
  109. then
  110.     echo shar: error transmitting "'README'" '(should have been 877 characters)'
  111. fi
  112. chmod +x 'README'
  113. fi # end of overwriting check
  114. echo shar: extracting "'dnamail.doc'" '(9031 characters)'
  115. if test -f 'dnamail.doc'
  116. then
  117.     echo shar: will not over-write existing file "'dnamail.doc'"
  118. else
  119. cat << \SHAR_EOF > 'dnamail.doc'
  120. 1) Intro
  121.  
  122.   Dnamail and dnamaild allow a Sun computer with the Sunlink/DNI software
  123.   to send and receive mail from VMS computers (may work with other DECnet
  124.   computers, but hasn't been tested).
  125.  
  126.   These programs cooperate with the sendmail program, so that users
  127.   do not need to use any special commands to send and receive mail.
  128.   This means that 'mailtool' may be used to read and compose messages.
  129.   Dnamail may also be used independently of sendmail, although message
  130.   editing is lacking.
  131.  
  132. 2) Installation
  133.  
  134.   >>    The DNI software has a bug that needs to be fixed before
  135.   >>    dnamail will work.  The bug is related to failure to read/write
  136.   >>    zero-length records.  You can get the patch from Sun 
  137.   >>    (bug #1007228), and possibly from the sun archives at rice.edu.
  138.   >>    You could possibly get them from me, but save this as a last resort.
  139.  
  140.   Look over 'Makefile' and 'dnamail.h'.  If you want to have dnamaild
  141.   run 'standalone', then uncomment the STANDALONE definition in
  142.   dnamail.h.  When dnamaild is compiled with the STANDALONE option, then
  143.   it will not automatically be called from dnaserver, but must be run
  144.   before you expect any mail to show up.  It will handle one mail connection
  145.   and then exit.  Obviously, this option is not too useful, but it helps
  146.   if you are trying to debug.
  147.  
  148.   Do 'make all'.  This should make the executables 'dnamail' and 'dnamaild'.
  149.  
  150.   Put the executables into /usr/sunlink/dna, or use a symbolic link.
  151.  
  152.   Add the following line to /usr/sunlink/dna/dnaserver.reg (if you want
  153.   to run dnamaild 'standalone', then you shouldn't do this):
  154.  
  155.      27    MAIL    /usr/sunlink/dna/dnamaild
  156.  
  157.   Modify sendmail.cf appropriately and restart sendmail.
  158.  
  159.   Test...  Before making sendmail.cf changes, you can try
  160.   running dnamail directly - just type /usr/sunlink/dna/dnamail.
  161.   After making the sendmail.cf changes, you can test by just sending
  162.   mail.
  163.  
  164. 3) Sendmail.cf changes
  165.  
  166.   In order to have dnamail and dnamaild cooperate with sendmail, changes
  167.   must be made to /usr/lib/sendmail.cf. 
  168.  
  169.   >>  If you have made changes to sendmail.cf before, or no someone
  170.   >>  who has, then the modifications will be relatively straightforward.
  171.   >>  If you don't fit into the above category, then I suggest that you
  172.   >>  read the 'Sendmail Installation and Operation' tutorial in the
  173.   >>  Sun system administrators guide to familiarize yourself with
  174.   >>  sendmail.
  175.  
  176.   On the Sun installation tape(s), sendmail.cf came in two forms,
  177.   sendmail.main.cf and sendmail.subsidiary.cf.  With dnamail, there
  178.   are four combinations - main, subsidiary, sub_decnet, and main_decnet.
  179.   Remember to make a symbolic link to the correct file on each machine
  180.   (see the Sun system administrators manual).
  181.  
  182.   'diff' output is included in this distribution showing the changes to
  183.   be made to the original sendmail.main.cf and sendmail.subsidiary.cf
  184.   so that they will handle DECnet.  If you have not changed your
  185.   original .cf much from the original SMI-3.2 version, then the patches
  186.   may work as is.  If not, then use the patches and the following
  187.   instructions as a guide.  Even if patch works, you still need
  188.   to read these instructions (two other files need changing).
  189.  
  190.   Briefly - use patch to create new version of the .cf files.  Then for
  191.   every Sun that runs DNI, uncomment the 'DSdnahost' line for it (use
  192.   a private copy!).
  193.  
  194.   REMEMBER:  Make backups of the original .cf files!!  It also helps
  195.              to comment each of the lines you changed.
  196.  
  197.   Here are the basic changes.  Anything that looks like multiple spaces
  198.   should actually be a tab.
  199.  
  200.   - in /etc/hosts, add 'dnahost' as an alternate name for the machine
  201.     you want to be the DECnet relay.  For example, my site has:
  202.  
  203.     192.9.200.1    nova dnahost
  204.  
  205.     If you have more than one machine running Sunlink/DNI, then pick
  206.     one machine to be the relay for machines without Sunlink/DNI.
  207.  
  208.   - Edit a file called "/usr/sunlink/dna/dnahosts" to contain a list of
  209.     all VMS/DECnet nodes you want to send mail to, one node per line.
  210.     You do not need to have ALL the VMS machines listed, just the ones
  211.     you want to send mail to (a listed machine can deliver mail to a machine
  212.     that you didn't list).
  213.  
  214.   - Add the following lines somewhere near the beginning of sendmail.main.cf
  215.     and sendmail.subsidiary.cf.
  216.  
  217.     # Major decnet relay (relayed by #ether)
  218.     DSdnahost
  219.     # get list of decnet machines we want to be able to send mail to
  220.     FS/usr/sunlink/dna/dnahosts
  221.  
  222.     The DS line defines a macro, $S, to be the name of the machine that will
  223.     actually connect to DECnet.  Any machine that can't handle DECnet mail
  224.     will forward any DECnet mail to this machine to handle it instead.
  225.     If all your machines are on DECnet, then you don't need to do this.
  226.     If you already have a $S macro (search for ^DS in vi), then choose an
  227.     unused macro instead.
  228.  
  229.     The FS line defines a class, $S, that defines the VMS nodes
  230.     we can send mail to with dnamail.
  231.    
  232.   - Add 'dna' as a trusted user.  Look for the following lines in
  233.     sendmail.main.cf and sendmail.subsidiary.cf:
  234.  
  235.     Troot
  236.     Tdaemon
  237.     Tuucp
  238.  
  239.     and add the following line to these:
  240.  
  241.     Tdna
  242.  
  243.   - In sendmail.main.cf (only), look for the following lines (in ruleset 0):
  244.  
  245.     # resolve UUCP domain
  246.     R<@$-.uucp>:$+        $#uucp    $@$1 $:$2    @host.uucp:...
  247.  
  248.     and add these next lines BEFORE them:
  249.  
  250.         ####################################################
  251.         #  If $S (decnet gateway) is defined, then forward to $S, else
  252.         #  resolve to dna mailer.
  253.         ####################################################
  254.         R$+<@$=S>        $?S $#ether $@$S $:$2!$1 $| $#dna $@$2 $:$1 $.
  255.         R$+<@$=S.uucp>        $?S $#ether $@$S $:$2!$1 $| $#dna $@$2 $:$1 $.
  256.  
  257.     (If you aren't using 'S' as the macro for 'dnahost', then subsitute
  258.     in the macro letter you are using).
  259.  
  260.   - In sendmail.subsidiary.cf (only), look for the following lines
  261.     (in ruleset 0):
  262.  
  263.         # optimize names of known ethernet hosts
  264.         R$*<@$*$%y.LOCAL>$*    $#ether $@$3 $:$1<@$2$3>$4    user@host.here
  265.  
  266.     and add these next lines BEFORE them:
  267.  
  268.         ####################################################
  269.         #  If $S (decnet gateway) is defined, then forward to $S, else
  270.         #  resolve to dna mailer.
  271.         ####################################################
  272.         R$+<@$=S>        $?S $#ether $@$S $:$2!$1 $| $#dna $@$2 $:$1 $.
  273.         R$+<@$=S.uucp>        $?S $#ether $@$S $:$2!$1 $| $#dna $@$2 $:$1 $.
  274.  
  275.     (If you aren't using 'S' as the macro for 'dnahost', then subsitute
  276.     in the macro letter you are using).
  277.  
  278.   - Add the following lines to sendmail.main.cf and sendmail.subsidiary.cf
  279.     (at the end of the file, or grouped with the other mailer definitions):
  280.  
  281.     ############################################################
  282.     ############################################################
  283.     #####
  284.     #####        DECnet Mailer specification
  285.     #####
  286.     #####    Messages processed by this configuration are assumed to leave
  287.     #####   the internet domain.  Hence, they may not necessarily correspond
  288.     #####    to RFC822 in all details.
  289.     #####
  290.     ############################################################
  291.     ############################################################
  292.  
  293.     Mdna,    P=/usr/sunlink/dna/dnamail, F=mnSF, S=14, R=24,
  294.         A=dnamail -f $f -n $h $u
  295.  
  296.     S14
  297.     # none needed
  298.     S24
  299.     # none needed
  300.  
  301.   - Now copy sendmail.main.cf to sendmail.main_decnet.cf.  Also copy
  302.     sendmail.subsidiary.cf to sendmail.sub_decnet.cf.  Edit both of
  303.     these new files and change the following line:
  304.  
  305.     DSdnahost
  306.  
  307.     to:
  308.  
  309.     # DSdnahost
  310.  
  311.     (this comments the line out).  This one line should be the only change.
  312.     Now for each machine that is a valid DECnet node, make a link from
  313.     sendmail.cf (in /private/usr/lib for standard installations) to
  314.     sendmail.main_decnet.cf or sendmail.sub_decnet.cf.  Depending upon
  315.     whether the machine is a main mail machine or not, use one of the
  316.     following commands:
  317.  
  318.     ln -s /usr/lib/sendmail.main_decnet.cf /private/usr/lib/sendmail.cf
  319.     or
  320.     ln -s /usr/lib/sendmail.sub_decnet.cf /private/usr/lib/sendmail.cf
  321.  
  322.   That's it!! After making the changes, you need to restart sendmail.
  323.   Since sendmail does not have the capability of 're-reading' the 
  324.   configuration file, you will have to stop the currently running
  325.   sendmail, and then run it again (as root) with the same parameters
  326.   as the old invocation (usually, /usr/lib/sendmail -bd -q1h).
  327.  
  328. 4) Usage
  329.  
  330.   If the installation has gone smoothly, everything should
  331.   be nearly transparent to users.
  332.  
  333.   To send mail from Sun to VAX, use an address like:
  334.  
  335.     vmsnode!user
  336.  
  337.   To send mail fromt VAX to Sun, use an address like:
  338.  
  339.     SUNNODE::"user"
  340.  
  341.   The quotes (") are necessary so that VMS mail does not convert
  342.   everything to uppercase.  Longer addresses are just as easy:
  343.  
  344.     SUNNODE::"node1!node2!..."
  345.  
  346.   (In this case, leaving off the quotes causes the '!' to be treated as
  347.   comment characters).  To set mail to be forwarded from the vax, you will
  348.   have to use 3 quotes instead of one:
  349.  
  350.     SET FORWARD SOMESUN::"""someuser"""
  351. SHAR_EOF
  352. if test 9031 -ne "`wc -c < 'dnamail.doc'`"
  353. then
  354.     echo shar: error transmitting "'dnamail.doc'" '(should have been 9031 characters)'
  355. fi
  356. chmod +x 'dnamail.doc'
  357. fi # end of overwriting check
  358. echo shar: extracting "'dnamail.h'" '(460 characters)'
  359. if test -f 'dnamail.h'
  360. then
  361.     echo shar: will not over-write existing file "'dnamail.h'"
  362. else
  363. cat << \SHAR_EOF > 'dnamail.h'
  364.   /* these lines get compiled into every object file */
  365. static char *version = "DnaMail (v1.1)";
  366. static char *CopyRight 
  367.     = "Copyright (C) D. B. Johnson, Feb., 1988; Lockheed Missiles & Space";
  368.  
  369. /* uncomment this if you want to run standalone */
  370. /* #define STANDALONE */
  371.  
  372. /* local defines */
  373. #define MAXLINE 256
  374. #define MAIL_OBJECT 27
  375. #define TMPFILE "/tmp/dnamail.XXXXXX"
  376.  
  377. #define TRUE 1
  378. #define FALSE 0
  379.  
  380. /* external routines */
  381. char *copystr(), *mailtime();
  382. SHAR_EOF
  383. if test 460 -ne "`wc -c < 'dnamail.h'`"
  384. then
  385.     echo shar: error transmitting "'dnamail.h'" '(should have been 460 characters)'
  386. fi
  387. chmod +x 'dnamail.h'
  388. fi # end of overwriting check
  389. echo shar: extracting "'dnamail.c'" '(11700 characters)'
  390. if test -f 'dnamail.c'
  391. then
  392.     echo shar: will not over-write existing file "'dnamail.c'"
  393. else
  394. cat << \SHAR_EOF > 'dnamail.c'
  395. /*************************************************************
  396.  * DNAMAIL - Deliver mail to remote DECnet nodes.
  397.  * Use interactively or with sendmail interface
  398.  *
  399.  * Copyright
  400.  *  Darin Johnson, Lockheed Missiles and Space
  401.  *
  402.  * Permission to copy and/or modify as long as reference is made
  403.  * to the authors.  This program may not be sold.
  404.  *************************************************************/
  405.  
  406. #include <stdio.h>
  407. #include <fcntl.h>
  408. #include <pwd.h>
  409. #include <ctype.h>
  410. #include <sysexits.h>        /* the 'proper' exits to return to sendmail */
  411. #include <sys/ioctl.h>
  412. #include <netdna/dna.h>
  413. #include <sys/time.h>
  414. #include "dnamail.h"
  415.  
  416. /* list of strings */
  417. struct clist {
  418.   char *str;
  419.   struct clist *next;
  420. };
  421.  
  422. extern int errno;
  423.  
  424. char *use_str = "USAGE: %s [-d] [-s subject] [-n node] [address-list]\n";
  425. #define usage() printf(use_str, argv[0])
  426.   
  427. char buff[MAXLINE];
  428. char *subject;
  429. char *node;
  430. char debug;
  431. char ttyflag;
  432. char *from;
  433. char *from_o;
  434. int num_addr;
  435. char *to_line;
  436. int baduser_flag;
  437.  
  438. char **to;    /* char *to[] */
  439.  
  440. int ll;            /* DECnet file descriptor */
  441.  
  442. /* open DECnet connection to mail protocol.  Descriptor is in 'll' */
  443. get_connection() {
  444.   OpenBlock ob;            /* info for opening DECnet link */
  445.   int ret;            /* return status code */
  446.  
  447.   if (debug)
  448.     fprintf(stderr, "Trying to open /dev/dna\n");
  449.  
  450.   if ((ll = open("/dev/dna", O_RDWR)) < 0) {
  451.     dnaerror("Open failed");
  452.     exit(EX_SOFTWARE);
  453.   }
  454.  
  455.   if (debug)
  456.     fprintf(stderr, "Trying to get logical link\n");
  457.  
  458.   if (ioctl(ll, SES_GET_LINK, 0)) {
  459.     dnaerror("Error getting logical link");
  460.     exit_with_status();
  461.   }
  462.  
  463.   if (debug)
  464.     fprintf(stderr, "Trying to get link to mail server on remote node\n");
  465.   
  466.     /* set up open block with access information */
  467.   strcpy(ob.op_node_name, node);  /* node we want to send mail to */
  468.   ob.op_object_nbr = MAIL_OBJECT;
  469.   ob.op_userid[0] = ob.op_account[0] = ob.op_password[0] = NULL;
  470.   ob.op_opt_data.im_length = 0;
  471.   if (ioctl(ll, SES_LINK_ACCESS, &ob) < 0) {
  472.     dnaerror("link access");
  473.     exit_with_status();
  474.   }
  475.   
  476.   if (debug)
  477.     fprintf(stderr, "Link established...\n");
  478.   /* ll now contains descriptor to open DECnet connection to MAIL.EXE on
  479.      node 'node' */
  480. }
  481.  
  482. /* convert dna errors into errors sendmail can understand.  Then exit. */
  483. exit_with_status() {
  484.   switch(errno) {
  485.   case NET_RESOUR:
  486.   case NODE_DOWN:
  487.   case NODE_UNREACH:
  488.     exit(EX_TEMPFAIL);
  489.   case NODE_NAME:
  490.     exit(EX_NOHOST);
  491.   case OBJ_NAME:
  492.     exit(EX_UNAVAILABLE);
  493.   default:
  494.     exit(EX_PROTOCOL);
  495.   }
  496. }
  497.  
  498. /* close up connection */
  499. drop_connection() {
  500.   SessionData sd;        /* misc session info */
  501.  
  502.   sd.sd_reason = 0;
  503.   sd.sd_data.im_length = 0;
  504.   ioctl(ll, SES_DISCONNECT, &sd);
  505.   close(ll);
  506.   if (debug)
  507.     fprintf(stderr, "Connection terminated by us\n");
  508. }
  509.  
  510. /* Sends headers.  Collects headers from message into a list.  Then
  511.    sends subject line (which terminates VMS header) followed by other
  512.    headers (which are treated as part of the normal message by VMS).
  513.  
  514.    The actual reason this routine exists is to search for a Subject:
  515.    line so it can be sent as the DECnet subject line.  Of course,
  516.    later versions of the software might do more with these headers. */
  517. send_headers() {
  518.   struct clist *headers, *tail;
  519.  
  520.   if (ttyflag || subject) {
  521.         /* if we are a tty or have an explicit subject */
  522.         /* then we only want to send the subject rather than search for it */
  523.       send(subject);
  524.       return;
  525.   }
  526.   sprintf(buff, "Received: by %s; %s", version, mailtime());
  527.     /* initialize list of headers */
  528.   headers = (struct clist*)malloc(sizeof(struct clist));
  529.   headers->next = NULL;
  530.   headers->str = copystr(buff);
  531.   tail = headers;
  532.     /* read in headers */
  533.   while (gets(buff) > 0) {
  534.       /* add onto header list */
  535.     tail->next = (struct clist*)malloc(sizeof(struct clist));
  536.     tail = tail->next;
  537.     tail->next=NULL;
  538.     tail->str = copystr(buff);
  539.     if (strlen(buff) == 0)    /* empty line means no more headers */
  540.       break;
  541.     if (!strncmp(buff, "Subject: ", 9)) {    /* found the Subject: */
  542.       subject = &tail->str[9];
  543.     }
  544.   }
  545.     /* now write out header lines */
  546.   send(subject);        /* this terminates the DECnet mail header */
  547.   tail=headers;
  548.     /* send list of headers - these are treated by DECnet mail as part of
  549.        the normal message */
  550.   while (tail) {
  551.     send(tail->str);
  552.     tail=tail->next;
  553.     cfree(headers->str);
  554.     free(headers);
  555.     headers=tail;
  556.   }
  557. }
  558.  
  559. /* the actual workhorse.  Sends mail using correct DECnet mail protocol.
  560.    Information about the protocol was derived from microfiche VMS
  561.    listings for V4.0.  See dnamaild.c for the other half of the protocol.
  562.  
  563.    Protocol:
  564.      'send' means to write a record over decnet.  A 'marker' is a record
  565.      containing a single NULL (used to terminate list of users and
  566.      message).
  567.      1) send who this mail is from (becomes From: line)
  568.      2) for each user we are sending mail to:
  569.         a) send address
  570.         b) get status back (tells us if address is valid or not)
  571.      3) send a 'marker' specifying the end of step 2
  572.      4) send To: line.  This line contains the original list
  573.         of recipients as entered by the user.  (this line is
  574.         treated as a 'header' by VMS)
  575.      5) send Subj: line (this is handled by send_headers() )
  576.      6) send each line of the message
  577.      7) terminate message with a 'marker'.
  578.      8) For each address that was valid in step 2, read a status value
  579.         back to see if message actually got sent.
  580. */
  581. send_message() {
  582.   int i;
  583.  
  584.   if (debug)
  585.     fprintf(stderr, "Send the From: line\n");
  586.   send(from);
  587.   
  588.     /* for each user, send address and get status */
  589.   baduser_flag = 0;
  590.   for (i=0; i<num_addr; i++) {
  591.     if (debug)
  592.       fprintf(stderr, "Checking user <%s>\n", to[i]);
  593.     send(to[i]);
  594.     if (check_status()) {    /* status tell if deliverable or not */
  595.       if (debug)
  596.         fprintf(stderr, "\tcheck_status returned true\n");
  597.       to[i] = NULL; 
  598.       baduser_flag = 1;  /* remember that we had an invalid address */
  599.     }
  600.   }
  601.   send_marker();    /* specifies end of address check */
  602.  
  603.   if (debug)
  604.     fprintf(stderr, "sending To: line\n");
  605.   send (to_line);
  606.  
  607.     /* send_headers() will send the Subj: line after parsing the headers */
  608.   send_headers();
  609.  
  610.     /* now send actual message */
  611.   if (debug)
  612.     fprintf(stderr, "Sending message body\n");
  613.   if (ttyflag)
  614.     printf("Enter your message below.  Press CTRL/D when complete, or CTRL/C to quit:\n");
  615.   while (gets(buff) > 0)
  616.     send(buff);
  617.   send_marker();  /* specifies end of message */
  618.  
  619.     /* for each address, check status to see if it was actually sent */
  620.   for (i=0; i<num_addr; i++)
  621.     if (to[i] && check_status())
  622.       baduser_flag = 1;  /* so we can exit with an appropriate error */
  623. }
  624.  
  625. /* read status back from remote node.  Since I am assuming the remote
  626.    node is a VAX, I assume a VAX byte order.  If there was an
  627.    error, then read in status message */
  628. int check_status() {
  629. #ifndef DEBUG
  630.   long st;
  631.     /* read longword */
  632.   if (read(ll, &st, sizeof(long)) < 0) {
  633.     dnaerror("CheckStatus");
  634.     exit_with_status();
  635.   }
  636.     /* 0x01000000 is really 0x1 on VAX */
  637.   if (st == 0x01000000)
  638.     return 0;
  639.     /* else we have an error - read error message */
  640.   while (1) {
  641.     if ((st=read(ll, buff, sizeof(buff))) < 0) {
  642.       dnaerror("CheckStatus");
  643.       exit_with_status();
  644.     }
  645.       /* is this end of status message ? */
  646.     if (st == 1 && buff[0] == NULL)
  647.       break;
  648.     buff[st] = NULL;
  649.     fprintf(stderr, "%s\n", buff);    /* write to stderr so sendmail sees it */
  650.   }
  651.   return 1;
  652. #else
  653.   return 0;
  654. #endif
  655. }
  656.  
  657. /* send a string over the decnet connection */
  658. send(s)
  659. char *s;
  660. {
  661. #ifndef DEBUG
  662.   if (write(ll, s, (s?strlen(s):0)) < 0) {
  663.     dnaerror("SEND");
  664.     exit_with_status();
  665.   }
  666. #else
  667. printf("SEND= %s\n", (s?s:""));
  668. #endif
  669. }
  670.  
  671. /* send NULL over decnet link - used as marker */
  672. send_marker() {
  673. #ifndef DEBUG
  674.   if (write(ll, "", 1) < 0) {
  675.     dnaerror("SEND");
  676.     exit_with_status();
  677.   }
  678. #else
  679. printf("SEND_MARKER\n");
  680. #endif
  681. }
  682.  
  683. /* clean up addresses for VMS side - convert to uppercase, anything else
  684.    needed */
  685. char *fix_addr(addr)
  686. char *addr;
  687. {
  688.   char inquote, esc;
  689.   char *p;
  690.     /* make sure usernames are uppercase so that MAIL.EXE doesn't yell
  691.        at us */
  692.   inquote = 0;
  693.   for (p=buff; *addr; addr++) {
  694.     if (esc = (*addr=='\\')) 
  695.       addr++;
  696.     if (*addr=='"' && !esc) {
  697.       addr++;
  698.       inquote ^= 1;
  699.     }
  700.     if (!inquote && islower(*addr))
  701.       *p++ = toupper(*addr);
  702.     else
  703.       *p++ = *addr;
  704.   }
  705.   *p = NULL;
  706.   return copystr(buff);
  707. }
  708.  
  709. /* make one long address out of all specified on command line - append
  710.    "node::" to beginning of each.  Return in 'to_line' */
  711. get_addresses(argv, index, num_addresses)
  712. char *argv[];
  713. int index, num_addresses;
  714. {
  715.   int i;
  716.   int comma_flag;
  717.   comma_flag = 0;
  718.   num_addr = num_addresses;
  719.   to = (char **)malloc(sizeof(char *) * num_addr);
  720.   for (i=0; i<num_addr; i++) {
  721.     if (comma_flag)
  722.       strcat(buff, " ");
  723.     strcat(buff, node);
  724.     strcat(buff, "::");
  725.     strcat(buff, argv[i+index]);
  726.     to[i] = fix_addr(argv[i+index]);
  727.     comma_flag = 1;
  728.   }
  729.   to_line = copystr(buff);
  730. }
  731.  
  732. /* parse arguments, get anything not specified, and call send_message() */
  733. main(argc, argv)
  734.       int argc;
  735.       char *argv[];
  736. {
  737.   int st,            /* return status */
  738.        i;            /* misc. */
  739.  
  740.   extern char *optarg;        /* for use with getopt() */
  741.   extern int optind;
  742.   char opt;
  743.   char *copystr();
  744.   char *t1;
  745.   struct passwd *pw;
  746.  
  747.   subject = node = from = from_o = NULL;
  748.   debug = ttyflag = FALSE;
  749.   
  750.     /* parse arguments */
  751.   while ((opt=getopt(argc, argv, "ds:n:f:")) != EOF) {
  752.     switch(opt) {
  753.       case 'd':        /* debug flag */
  754.         debug = TRUE;
  755.     break;
  756.       case 's':        /* subject */
  757.         subject = optarg;
  758.     break;
  759.       case 'n':        /* remote node */
  760.     node = optarg;
  761.     break;
  762.       case 'f':        /* not included in usage()! */
  763.     from_o = optarg;
  764.     break;
  765.       default:
  766.     usage();
  767.     exit(EX_USAGE);
  768.     }
  769.   }
  770.  
  771.     /* see if we are a tty as opposed to sendmail */
  772.   ttyflag = isatty(0); 
  773.  
  774.     /* prompt for node if not specified */
  775.   if (!node) {
  776.     fputs("Node: ", stdout);
  777.     if (!gets(buff)) {
  778.       puts("Unexpected EOF");
  779.       exit(1);
  780.     }
  781.     node = copystr(buff);
  782.   }
  783.     /* uppercase node name */
  784.   for (t1 = node; *t1; t1++)
  785.     if (islower(*t1))
  786.       *t1 = toupper(*t1);
  787.  
  788.     /* get recipients if not specified */
  789.   if (!argv[optind]) {
  790.     fputs("To: ", stdout);
  791.     if (!gets(buff)) {
  792.       puts("Unexpected EOF");
  793.       exit(1);
  794.     }
  795.       /* create to[] array */
  796.     to = (char **)malloc(sizeof(char*));    /* room for one address */
  797.     to_line = copystr(buff);
  798.     num_addr = 1;
  799.     to[0] = fix_addr(buff);
  800.   } else {
  801.       /* build to_line and to[] from arguments */
  802.     get_addresses(argv, optind, (argc-optind));
  803.   }
  804.   
  805.     /* get subject if not specified */
  806.   if (!subject && ttyflag) {
  807.     fputs("Subject: ", stdout);
  808.     if (!gets(buff)) {
  809.       puts("Unexpected EOF");
  810.       exit(1);
  811.     }
  812.     subject = copystr(buff);
  813.   }
  814.  
  815.     /* figure out who this is from if not specified or this is a tty */
  816.   if (!from_o) {
  817.     t1 = (char *)getlogin();
  818.     if (!t1) {
  819.       pw = getpwuid(getuid());
  820.       t1 = pw->pw_name;
  821.     }
  822.     from_o = t1;
  823.   }
  824.   sprintf(buff, "\"%s\"", from_o);
  825.   from = copystr(buff);
  826.   
  827.   if (debug) {
  828.     fprintf(stderr, "From: '%s'\n", from);
  829.     fprintf(stderr, "To: <%s>", to_line);
  830.   }
  831.  
  832.    /* get connection, send mail, close connection */
  833. #ifndef DEBUG
  834.   get_connection();
  835. #endif
  836.   send_message();
  837. #ifndef DEBUG
  838.   drop_connection();
  839. #endif
  840.  
  841.     /* if mail wasn't sent to a user, then exit with appropriate
  842.        error code, so sendmail can take the appropriate action */
  843.   if (baduser_flag)
  844.     exit(EX_NOUSER);
  845.   else
  846.     exit(EX_OK);
  847. }
  848. SHAR_EOF
  849. if test 11700 -ne "`wc -c < 'dnamail.c'`"
  850. then
  851.     echo shar: error transmitting "'dnamail.c'" '(should have been 11700 characters)'
  852. fi
  853. chmod +x 'dnamail.c'
  854. fi # end of overwriting check
  855. echo shar: extracting "'dnamaild.c'" '(10282 characters)'
  856. if test -f 'dnamaild.c'
  857. then
  858.     echo shar: will not over-write existing file "'dnamaild.c'"
  859. else
  860. cat << \SHAR_EOF > 'dnamaild.c'
  861. /*************************************************************
  862. * DNAMAILD - handle remote mail from DECnet nodes.
  863. *
  864. * To use:
  865. *   If compiled with -DSTANDALONE, then just execute this program
  866. *   whenever you want to receive mail (only handles one connection).
  867. *
  868. *   Without the STANDALONE option, add a line like the following to
  869. *   /usr/sunlink/dna/dnaserver.reg:
  870. *
  871. *     27  MAIL  /usr/sunlink/dna/dnamaild
  872. *
  873. *   (Remember to add the line "Tdna" to sendmail.cf, since
  874. *   this program gets run as user "dna".  This is not needed if
  875. *   compiled with STANDALONE option.)
  876. *
  877. * Copyright
  878. *  Darin Johnson, Lockheed Missiles and Space
  879. *
  880. * Permission to copy and/or modify as long as reference is made
  881. * to the authors.  This program may not be sold.
  882. *************************************************************/
  883.  
  884. #include    <stdio.h>
  885. #include    <ctype.h>
  886. #include    <signal.h>
  887. #include    <fcntl.h>
  888. #include    <sys/ioctl.h>
  889. #include    <netdna/dna.h>
  890. #include    "dnamail.h"
  891.  
  892. /* External variable definitions */
  893. extern int errno;        /* External variable errno     */
  894.  
  895. /* Global data definitions */
  896. short ll;            /* Logical link identifier     */
  897. char buffer[MAXLINE];        /* Character buffer          */
  898. char *my_hostname;
  899. OpenBlock opblk;        /* OpenBlock              */
  900. Image16 idata;
  901. struct ses_io_type sesopts;
  902. SessionData sd = {0, {0, ""}};
  903.  
  904. FILE *tmpf;
  905. char tmp_name[32];
  906. char *from;
  907.  
  908.   /* list of addresses */
  909. typedef struct addr_struct {
  910.   char *addr;
  911.   struct addr_struct *next;
  912. } ADDRESS;
  913.  
  914. ADDRESS *addr_head, *addr_tail;
  915.  
  916.   /* use a variable, since ioctl() wants an address to this */
  917. short T_num = MAIL_OBJECT;
  918.  
  919. /* if we are not run from dnaserver, then we have to set up our own link */
  920. #ifdef STANDALONE
  921. get_connection() {        /* get decnet connection set up */
  922. int ret;
  923.  
  924. /*
  925.  * Before establishing a logical link, we must first
  926.  * open the logical link device, "/dev/dna". 
  927.  */
  928. if ((ll = open("/dev/dna", O_RDWR)) < 0)
  929. dna_exit("Open Fail");
  930.  
  931. if (ioctl(ll, SES_GET_LINK, 0)) 
  932. dna_exit("Error getting a logical link");
  933.  
  934. /*
  935.  * Next, we must register ourself as a server.
  936.  */
  937.  
  938. ret = ioctl(ll, SES_NUM_SERVER, &T_num);
  939. if (ret == -1)
  940. dna_exit("Server Registration Failed");
  941.  
  942. if (ioctl(ll, SES_GET_AI, &opblk) < 0)
  943. dna_exit("Ioctl Get AI Failed");
  944.  
  945. if (ioctl(ll, SES_ACCEPT, &sd) < 0)
  946. dna_exit("Ioctl Accept failed");
  947. }        /* end received Open Block */
  948. #endif STANDALONE
  949.  
  950. /* add address onto list */
  951. add_address(user)
  952. char *user;
  953. {
  954.   ADDRESS *tmpa;
  955.   tmpa = (ADDRESS*)malloc(sizeof(ADDRESS));
  956.   tmpa->addr = copystr(user);
  957.   tmpa->next = NULL;
  958.   if (addr_tail) {
  959.     addr_tail->next = tmpa;
  960.     addr_tail = tmpa;
  961.   } else {
  962.     addr_head = addr_tail = tmpa;
  963.   }
  964. }
  965.  
  966. /* deliver completed message to all recipients */
  967. deliver() {
  968. #ifdef DEBUG
  969.   return;
  970. #else
  971.   FILE *sm;
  972.   ADDRESS *tmp, *jnk;
  973.   char c;
  974.   int ret;
  975.  
  976.     /* close temporary file since we are done writing to it */
  977.   fclose(tmpf);
  978.     /* reopen it so we can send it */
  979.   tmpf = fopen(tmp_name, "r");
  980.   if (!tmpf) {
  981.     dna_exit("Can't open temp file");
  982.   }
  983.   tmp = addr_head;
  984.     /* loop through each recipient */
  985.   while (tmp!=NULL) {
  986.       /* build command */
  987.     sprintf(buffer, "/usr/lib/sendmail -oem -f \"%s\" %s",
  988.          from, tmp->addr);
  989. #ifdef DEBUG
  990.     fprintf(stderr, "cmd = <%s>\n", buffer);
  991. #endif
  992.       /* open pipe to sendmail command */
  993.     if (sm = popen(buffer, "w")) {
  994.       rewind(tmpf);
  995.     /* now copy temp file to pipe */
  996.       while ((c=getc(tmpf))!=EOF)
  997.     putc(c, sm);
  998.       ret = pclose(sm);
  999.         /* check errors */
  1000.       if (ret) {
  1001.     sprintf(buffer, "sendmail can't send to %s on %s", tmp->addr, my_hostname);
  1002.     status_err(buffer);    /* send status back to remote node */
  1003.       } else
  1004.     status_ok();    /* send status back to remote node */
  1005.     } else
  1006.       dna_exit("Can't connect to sendmail");
  1007.     /* now go to next address */
  1008.     jnk = tmp;
  1009.     tmp=tmp->next;
  1010.     cfree(jnk->addr);
  1011.     free(jnk);
  1012.   }
  1013.   fclose(tmpf);
  1014.   tmpf = NULL;
  1015. #endif
  1016. }
  1017.  
  1018. /* clean up username from VMS side -
  1019.      VMS format is:  USERNAME        "comment"
  1020.      we want:        USERNAME        (comment) 
  1021.    There also may be quotes around the username, so they get zapped.
  1022.    I am unsure of the exact format used by VMS, but this hasn't caused
  1023.    trouble so far...
  1024.    We also append the remote node name to the front.
  1025. */
  1026. fix_user(str)
  1027. char *str;
  1028. {
  1029.   char *fq, *lq;
  1030.   if (*str == '"') {    /* remove quotes around username */
  1031.     str++;
  1032.     fq = (char *)index(str, '"');
  1033.     *fq = ' ';
  1034.   } else {
  1035.     fq = (char *)index(str, '"');
  1036.     lq = (char *)rindex(str, '"');
  1037.     if (fq && lq && fq < lq) {
  1038.         /* convert quotes */
  1039.       *fq = '(';
  1040.       *lq = ')';
  1041.     }
  1042.   }
  1043.     /* we have to set this up for sendmail */
  1044.   from = (char *)calloc(strlen(str)+strlen(opblk.op_node_name)+5, 1);
  1045.   sprintf(from, "%s!%s", opblk.op_node_name, str);
  1046. }
  1047.  
  1048. /* Actually receive the mail.  Places all recipients into a list and
  1049.    saves the message/headers into a temporary file.  Mail protocol was
  1050.    derived from VMS microfiche.  See dnamail.c for other half of protocol.
  1051.  
  1052.    Protocol:
  1053.      1) read a record - if EOF, then exit
  1054.      2) record read in 1) is who the mail is "From:"
  1055.      3) loop until a 'marker' is read (record containing single NULL)
  1056.        a) read recipient address
  1057.        b) send back OK status (really, the status should tell if
  1058.       this address is good and/or the user exists, but I ignore
  1059.       this part since sendmail we mail errors back)
  1060.      4) read "To: line.  This is the line typed by the VMS mail user
  1061.     to specify the recipients.  Used only as part of the header.
  1062.      5) read "Subject:" line.  Used only as part of the header.
  1063.      6) keep reading message body until a 'marker' is seen.
  1064.      7) now send back a status for each address from 3a) above
  1065.     indicating whether the message was delivered or not.  (Note
  1066.     that we shouldn't send back a status if we sent back a bad
  1067.     status in 3b), which we don't do anyway)
  1068.      8) go to step 1), in case there are more messages being sent
  1069.     (in case VMS decides to 'cache' this link)
  1070. */
  1071. receive_mail() {
  1072.   int len, ret;
  1073.  
  1074.   while (1) {
  1075.     len=get(buffer);
  1076.     if (len < 0) {    /* no more messages being sent */
  1077. #ifdef DEBUG
  1078.       fprintf(stderr, "DONE!!\n");
  1079. #endif
  1080.       break;
  1081.     }
  1082.  
  1083.       /* add our own header for tracking purposes */
  1084.     fprintf(tmpf, "Received: by %s; %s\n", version, mailtime());
  1085.  
  1086. #ifdef DEBUG
  1087.     fprintf(stderr, "USER = <%*s>\n", len, buffer);
  1088. #endif
  1089.       /* record read above is USER */
  1090.     buffer[len]=NULL;
  1091.     fix_user(buffer);
  1092.     fprintf(tmpf, "From: %s\n", from);
  1093.       /* get list of recipients */
  1094.     while (1) {
  1095.       len = get(buffer);
  1096.       if (len==1 && buffer[0]==NULL) {        /* end of list */
  1097. #ifdef DEBUG
  1098.     fprintf(stderr, "(MARKER)\n");
  1099. #endif
  1100.     break;
  1101.       }
  1102. #ifdef DEBUG
  1103.       fprintf(stderr, "ADDR = <%*s>\n", len, buffer);
  1104. #endif
  1105.       buffer[len] = NULL;
  1106.       add_address(buffer);    /* add address to list */
  1107.       status_ok();    /* send back OK status since we aren't checking now */
  1108.     }      
  1109.  
  1110.       /* get the To: line */
  1111.     len = check_get(buffer);
  1112. #ifdef DEBUG
  1113.     fprintf(stderr, "TO = <%*s>\n", len, buffer);
  1114. #endif
  1115.     buffer[len] = NULL;
  1116.     fprintf(tmpf, "To: %s\n", buffer);
  1117.       /* get Subject: line */
  1118.     len = check_get(buffer);
  1119. #ifdef DEBUG
  1120.     fprintf(stderr, "SUBJ = <%*s>\n", len, buffer);
  1121. #endif
  1122.     buffer[len]=NULL;
  1123.     fprintf(tmpf, "Subject: %s\n", buffer);
  1124.     fprintf(tmpf, "\n");    /* mark end of headers */
  1125.       /* now get message */
  1126.     while (1) {
  1127.       len = check_get(buffer);
  1128.       if (len==1 && buffer[0]==NULL) {    /* end of message */
  1129. #ifdef DEBUG
  1130.     fprintf(stderr, "(MARKER)\n");
  1131. #endif
  1132.     break;
  1133.       }
  1134. #ifdef DEBUG
  1135.       fprintf(stderr, "TXT = <%*s>\n", len, buffer);
  1136. #endif
  1137.       buffer[len]=NULL;
  1138.       fprintf(tmpf, "%s\n", buffer);
  1139.     }
  1140. #ifdef DEBUG
  1141.     fprintf(stderr, "    Sending message\n");
  1142. #endif
  1143.       /* now try to deliver the message */
  1144.     deliver();
  1145.   }
  1146. }
  1147.  
  1148. /* send string over decnet link */
  1149. send(s, len)
  1150. char *s;
  1151. int len;
  1152. {
  1153.   if (write(ll, s, len) < 0)
  1154.     dna_exit("SEND");
  1155. }
  1156.  
  1157. /* do a get(), but check errors here */
  1158. int check_get(s)
  1159. char *s;
  1160. {
  1161.   int l;
  1162.   if ((l=get(s))<0)
  1163.     dna_exit("GET");
  1164. }
  1165.  
  1166. /* read a string from decnet link.  Return length of string. */
  1167. int get(s)
  1168. char *s;
  1169. {
  1170.   int len, readmask;
  1171.     /* using select() here since it was needed earlier in development,
  1172.        don't know if it is needed now */
  1173.   readmask = 1 << ll;
  1174.   if ((len=select(32, &readmask, 0, 0, 0)) < 0) {
  1175.     perror("select");
  1176.     my_exit(1);
  1177.   }
  1178.   if ((len=read(ll, s, MAXLINE)) >= 0)
  1179.     s[len] = NULL;    /* close off string */
  1180.   return len;
  1181. }
  1182.  
  1183. /* print out decnet error and call my_exit() */
  1184. dna_exit(str)
  1185. char *str;
  1186. {
  1187.     dnaerror(str);
  1188.     my_exit(1);
  1189. }
  1190.  
  1191. /* cleanup and then exit() */
  1192. my_exit(st)
  1193. int st;
  1194. {
  1195.   if (tmpf) {
  1196.     fclose(tmpf);
  1197. #ifndef DEBUG
  1198.     unlink(tmp_name);
  1199. #endif
  1200.   }
  1201.   exit(st);
  1202. }
  1203.  
  1204. /* send OK status up decnet link */
  1205. status_ok()
  1206. {
  1207.   long st;
  1208.   st = 0x01000000;    /* same as 0x1 on VAX */
  1209.   send(&st, sizeof(long));
  1210. }
  1211.  
  1212. /* send error status and message up decnet link */
  1213. status_err(msg)
  1214. char *msg;
  1215. {
  1216.   long st;
  1217.   st = 0x00000000;
  1218.   send(&st, sizeof(long));
  1219.   send(msg, strlen(msg));
  1220.   send("", 1);    /* mark end of message */
  1221. }
  1222.  
  1223. /* if we are standalone we call get_connection, otherwise
  1224.    dnaserver has passed number of file descriptor for logical link
  1225.    in argv */
  1226. main(argc, argv)
  1227. int argc;
  1228. char *argv[];
  1229. {
  1230.   int i;
  1231.     /* always a good practice to do this when creating temp files */
  1232.   for (i=0; i<20; i++)
  1233.     if (signal(i, SIG_IGN)!=SIG_IGN)
  1234.       signal(i, my_exit);
  1235.  
  1236.   gethostname(buffer, sizeof(buffer));
  1237.   my_hostname = copystr(buffer);
  1238.  
  1239. #ifdef STANDALONE
  1240.   get_connection();
  1241. #else
  1242.     /* set up ll to point be descriptor passed */
  1243.   if (argc<2 || (ll=atoi(argv[1]))==0) {
  1244.     fprintf(stderr, "%s: Aborting, should not be run interactively\n", argv[0]);
  1245.     exit(1);
  1246.   }
  1247.     /* accept link */
  1248.   if (ioctl(ll, SES_GET_AI, &opblk) < 0)
  1249.     dna_exit("Ioctl Get AI Failed");
  1250.   if (ioctl(ll, SES_ACCEPT, &sd) < 0)
  1251.     dna_exit("Ioctl Accept failed");
  1252. #endif
  1253.  
  1254.     /* create temp file */
  1255.   strcpy(tmp_name, TMPFILE),
  1256.   mktemp(tmp_name);
  1257.   tmpf = fopen(tmp_name, "w");
  1258.   addr_head = addr_tail = NULL;
  1259.  
  1260.     /* now read mail from link - actually we may have to wait around
  1261.        while the user types in the message, but this shouldn't bother
  1262.        us */
  1263.   receive_mail();
  1264.  
  1265.     /* cleanup */
  1266.   fclose(tmpf);
  1267.   unlink(tmp_name);
  1268.   close(ll);
  1269.   return;
  1270. }
  1271. SHAR_EOF
  1272. if test 10282 -ne "`wc -c < 'dnamaild.c'`"
  1273. then
  1274.     echo shar: error transmitting "'dnamaild.c'" '(should have been 10282 characters)'
  1275. fi
  1276. chmod +x 'dnamaild.c'
  1277. fi # end of overwriting check
  1278. echo shar: extracting "'dnamisc.c'" '(794 characters)'
  1279. if test -f 'dnamisc.c'
  1280. then
  1281.     echo shar: will not over-write existing file "'dnamisc.c'"
  1282. else
  1283. cat << \SHAR_EOF > 'dnamisc.c'
  1284. /*************************************************************
  1285.   miscellaneous routines
  1286.  *************************************************************/
  1287.  
  1288. #include <stdio.h>
  1289. #include <sys/time.h>
  1290.  
  1291. /* returns a newly allocated copy of a string */
  1292. char *copystr(str)
  1293.       char *str;
  1294. {
  1295.   char *tmp, *calloc();
  1296.   if (!str)
  1297.     return NULL;
  1298.   tmp = calloc(strlen(str)+1, 1);
  1299.   strcpy(tmp, str);
  1300.   return tmp;
  1301. }
  1302.  
  1303. /* figure out correct time and timezone */
  1304. char *mailtime() {
  1305.   long my_time;
  1306.   char *atime;
  1307.   static char buf[32];
  1308.   struct timeval tv;
  1309.   struct timezone tzp;
  1310.   my_time = time(0L);
  1311.   atime = asctime(localtime(&my_time));
  1312.   atime[strlen(atime)-1] = '\0';    /* zap "\n" */
  1313.   gettimeofday(&tv, &tzp);
  1314.   sprintf(buf, "%s %s", atime, timezone(tzp.tz_minuteswest, tzp.tz_dsttime));
  1315.   return buf;
  1316. }
  1317. SHAR_EOF
  1318. if test 794 -ne "`wc -c < 'dnamisc.c'`"
  1319. then
  1320.     echo shar: error transmitting "'dnamisc.c'" '(should have been 794 characters)'
  1321. fi
  1322. chmod +x 'dnamisc.c'
  1323. fi # end of overwriting check
  1324. echo shar: extracting "'dnaerror.c'" '(474 characters)'
  1325. if test -f 'dnaerror.c'
  1326. then
  1327.     echo shar: will not over-write existing file "'dnaerror.c'"
  1328. else
  1329. cat << \SHAR_EOF > 'dnaerror.c'
  1330. /* Since dnaerror.c is copyrighted, this file just includes the copy    */
  1331. /* you should already have.  You may have to change the path name if    */
  1332. /* your setup is not standard.  If you don't have this file (even    */
  1333. /* on the original tape), then you will have to get one from Sun,    */
  1334. /* or derive your own.                            */
  1335. /*                                    */
  1336. /* All dnaerror does, is to simulate perror(), but with DECNET errors    */
  1337. /* if they apply.                            */
  1338.  
  1339. #include "/usr/sunlink/dna/tests/dnaerror.c"
  1340. SHAR_EOF
  1341. if test 474 -ne "`wc -c < 'dnaerror.c'`"
  1342. then
  1343.     echo shar: error transmitting "'dnaerror.c'" '(should have been 474 characters)'
  1344. fi
  1345. chmod +x 'dnaerror.c'
  1346. fi # end of overwriting check
  1347. echo shar: extracting "'main.diff'" '(3720 characters)'
  1348. if test -f 'main.diff'
  1349. then
  1350.     echo shar: will not over-write existing file "'main.diff'"
  1351. else
  1352. cat << \SHAR_EOF > 'main.diff'
  1353. This is a diff to convert sendmail.main.cf to use dnamail.
  1354.  
  1355. Changes:
  1356.  
  1357.   1) Define macro 'S' to be name of machine that can forward DECnet
  1358.      mail (default is 'dnahost').  Comment out this line for
  1359.      if this machine runs Sunlink/DNI.
  1360.   2) Define class 'S' to be list of machines we can send mail to
  1361.      via DECnet.
  1362.   3) Add 'dna' as a trusted user.
  1363.   4) Add 'dna' as a mailer
  1364.   5) Addresses to machines in class 'S' are mailed by #dna
  1365.      or forwarded to 'dnahost' to be mailed.
  1366.  
  1367. *** sendmail.main.cf    Sat May  7 18:43:55 1988
  1368. --- sendmail.main.new    Sat May  7 19:10:07 1988
  1369. ***************
  1370. *** 48,53 ****
  1371. --- 48,58 ----
  1372.   # Otherwise, the default is to use the hosts.byname map if YP
  1373.   # is running (or else the /etc/hosts file if no YP).
  1374.   
  1375. + # define this $S if you want to forward decnet mail to $S
  1376. + # if this node can handle decnet, then DON'T define $S
  1377. + # DBJ
  1378. + DSdnahost
  1379.   #################################################
  1380.   #
  1381.   #    General configuration information
  1382. ***************
  1383. *** 91,96 ****
  1384. --- 96,104 ----
  1385.   DVSMI-3.2
  1386.   
  1387.   
  1388. + # get list of decnet machines we can send mail to
  1389. + FS/usr/sunlink/dna/dnahosts
  1390.   ##########################
  1391.   ###   Special macros   ###
  1392.   ##########################
  1393. ***************
  1394. *** 154,163 ****
  1395.   #########################
  1396.   ###   Trusted users   ###
  1397.   #########################
  1398.   Troot
  1399.   Tdaemon
  1400.   Tuucp
  1401.   
  1402.   #############################
  1403.   ###   Format of headers   ###
  1404. --- 162,174 ----
  1405.   #########################
  1406.   ###   Trusted users   ###
  1407.   #########################
  1408. ! #
  1409. ! # added dna, since dnamaild gets run as that user..
  1410. ! #
  1411.   Troot
  1412.   Tdaemon
  1413.   Tuucp
  1414. + Tdna
  1415.   
  1416.   #############################
  1417.   ###   Format of headers   ###
  1418. ***************
  1419. *** 269,274 ****
  1420. --- 280,287 ----
  1421.   S6
  1422.   R$*<@$*$=D>$*        $1<@$2LOCAL>$4            convert local domain
  1423.   R$*<@$*$=D.$=U>$*    $1<@$2LOCAL>$5            or full domain name
  1424. + #added by DBJ - just in case someone still uses the old form
  1425. + R$*<$*.decnet>$*    $1<$2.uucp>$3            convert to uucp
  1426.   
  1427.   ############################################################
  1428.   ############################################################
  1429. ***************
  1430. *** 366,373 ****
  1431. --- 379,408 ----
  1432.   S23
  1433.   R$+            $:$>5$1                convert to old style
  1434.   
  1435. + ############################################################
  1436. + ############################################################
  1437. + #####
  1438. + #####        DECnet Mailer specification
  1439. + #####
  1440. + #####    Messages processed by this configuration are assumed to leave
  1441. + #####   the internet domain.  Hence, they may not necessarily correspond
  1442. + #####    to RFC822 in all details.
  1443. + #####
  1444. + #####   added by DBJ
  1445. + #####
  1446. + ############################################################
  1447. + ############################################################
  1448.   
  1449. + Mdna,    P=/usr/sunlink/dna/dnamail, F=mnSF, S=14, R=24,
  1450. +     A=dnamail -f $f -n $h $u
  1451.   
  1452. + S14
  1453. + # none needed
  1454. + S24
  1455. + # none needed
  1456.   ############################################################
  1457.   ############################################################
  1458.   #####
  1459. ***************
  1460. *** 415,420 ****
  1461. --- 450,470 ----
  1462.   
  1463.   # Clean up addresses for external use -- kills LOCAL, route-addr ,=>: and etc.
  1464.   R$*            $:$>9 $1            Then continue...
  1465. + # added by DBJ
  1466. + ####################################################
  1467. + #  This gets shoved in the center of Ruleset 0 in 
  1468. + #  order to handle decnet nodes.
  1469. + #
  1470. + #  If $S (decnet gateway) is defined, then forward to $S, else
  1471. + #  resolve to dna mailer.
  1472. + #
  1473. + #  added by DBJ
  1474. + ####################################################
  1475. + R$+<@$=S>        $?S $#ether $@$S $:$2!$1 $| $#dna $@$2 $:$1 $.
  1476. + R$+<@$=S.uucp>        $?S $#ether $@$S $:$2!$1 $| $#dna $@$2 $:$1 $.
  1477.   
  1478.   # resolve UUCP domain
  1479.   R<@$-.uucp>:$+        $#uucp  $@$1 $:$2        @host.uucp:...
  1480. SHAR_EOF
  1481. if test 3720 -ne "`wc -c < 'main.diff'`"
  1482. then
  1483.     echo shar: error transmitting "'main.diff'" '(should have been 3720 characters)'
  1484. fi
  1485. chmod +x 'main.diff'
  1486. fi # end of overwriting check
  1487. echo shar: extracting "'sub.diff'" '(3714 characters)'
  1488. if test -f 'sub.diff'
  1489. then
  1490.     echo shar: will not over-write existing file "'sub.diff'"
  1491. else
  1492. cat << \SHAR_EOF > 'sub.diff'
  1493. This is a diff to convert sendmail.subsidiary.cf to use dnamail.
  1494.  
  1495. Changes:
  1496.  
  1497.   1) Define macro 'S' to be name of machine that can forward DECnet
  1498.      mail (default is 'dnahost').  Comment out this line for
  1499.      if this machine runs Sunlink/DNI.
  1500.   2) Define class 'S' to be list of machines we can send mail to
  1501.      via DECnet.
  1502.   3) Add 'dna' as a trusted user.
  1503.   4) Add 'dna' as a mailer
  1504.   5) Addresses to machines in class 'S' are mailed by #dna
  1505.      or forwarded to 'dnahost' to be mailed.
  1506.  
  1507. *** sendmail.subsidiary.cf    Sat May  7 18:43:55 1988
  1508. --- sendmail.subsidiary.new    Sat May  7 19:10:58 1988
  1509. ***************
  1510. *** 36,41 ****
  1511. --- 36,46 ----
  1512.   DRmailhost
  1513.   CRmailhost
  1514.   
  1515. + # define this $S if you want to forward decnet mail to $S
  1516. + # if this node can handle decnet, then DON'T define $S
  1517. + # DBJ
  1518. + DSdnahost
  1519.   #################################################
  1520.   #
  1521.   #    General configuration information
  1522. ***************
  1523. *** 79,84 ****
  1524. --- 84,92 ----
  1525.   DVSMI-3.2
  1526.   
  1527.   
  1528. + # get list of decnet machines we can send mail to
  1529. + FS/usr/sunlink/dna/dnahosts
  1530.   ##########################
  1531.   ###   Special macros   ###
  1532.   ##########################
  1533. ***************
  1534. *** 142,151 ****
  1535.   #########################
  1536.   ###   Trusted users   ###
  1537.   #########################
  1538.   Troot
  1539.   Tdaemon
  1540.   Tuucp
  1541.   
  1542.   #############################
  1543.   ###   Format of headers   ###
  1544. --- 150,162 ----
  1545.   #########################
  1546.   ###   Trusted users   ###
  1547.   #########################
  1548. ! #
  1549. ! # added dna, since dnamaild gets run as that user..
  1550. ! #
  1551.   Troot
  1552.   Tdaemon
  1553.   Tuucp
  1554. + Tdna
  1555.   
  1556.   #############################
  1557.   ###   Format of headers   ###
  1558. ***************
  1559. *** 257,262 ****
  1560. --- 268,275 ----
  1561.   S6
  1562.   R$*<@$*$=D>$*        $1<@$2LOCAL>$4            convert local domain
  1563.   R$*<@$*$=D.$=U>$*    $1<@$2LOCAL>$5            or full domain name
  1564. + #added by DBJ - just in case someone still uses the old form
  1565. + R$*<$*.decnet>$*    $1<$2.uucp>$3            convert to uucp
  1566.   
  1567.   ############################################################
  1568.   ############################################################
  1569. ***************
  1570. *** 354,360 ****
  1571. --- 367,396 ----
  1572.   S23
  1573.   R$+            $:$>5$1                convert to old style
  1574.   
  1575. + ############################################################
  1576. + ############################################################
  1577. + #####
  1578. + #####        DECnet Mailer specification
  1579. + #####
  1580. + #####    Messages processed by this configuration are assumed to leave
  1581. + #####   the internet domain.  Hence, they may not necessarily correspond
  1582. + #####    to RFC822 in all details.
  1583. + #####
  1584. + #####   added by DBJ
  1585. + #####
  1586. + ############################################################
  1587. + ############################################################
  1588.   
  1589. + Mdna,    P=/usr/sunlink/dna/dnamail, F=mnSF, S=14, R=24,
  1590. +     A=dnamail -f $f -n $h $u
  1591. + S14
  1592. + # none needed
  1593. + S24
  1594. + # none needed
  1595.   ############################################################
  1596.   ############################################################
  1597.   #####
  1598. ***************
  1599. *** 407,412 ****
  1600. --- 443,463 ----
  1601.   R<@$=V.uucp>:$+        $:$>9 $1            First clean up, then...
  1602.   R<@$=V.uucp>:$+        $#uucp  $@$1 $:$2        @host.uucp:...
  1603.   R$+<@$=V.uucp>        $#uucp  $@$2 $:$1        user@host.uucp
  1604. + # added by DBJ
  1605. + ####################################################
  1606. + #  This gets shoved in the center of Ruleset 0 in 
  1607. + #  order to handle decnet nodes.
  1608. + #
  1609. + #  If $S (decnet gateway) is defined, then forward to $S, else
  1610. + #  resolve to dna mailer.
  1611. + #
  1612. + #  added by DBJ
  1613. + ####################################################
  1614. + R$+<@$=S>        $?S $#ether $@$S $:$2!$1 $| $#dna $@$2 $:$1 $.
  1615. + R$+<@$=S.uucp>        $?S $#ether $@$S $:$2!$1 $| $#dna $@$2 $:$1 $.
  1616.   
  1617.   # optimize names of known ethernet hosts
  1618.   R$*<@$*$%y.LOCAL>$*    $#ether $@$3 $:$1<@$2$3>$4    user@host.here
  1619. SHAR_EOF
  1620. if test 3714 -ne "`wc -c < 'sub.diff'`"
  1621. then
  1622.     echo shar: error transmitting "'sub.diff'" '(should have been 3714 characters)'
  1623. fi
  1624. chmod +x 'sub.diff'
  1625. fi # end of overwriting check
  1626. #    End of shell archive
  1627. exit 0
  1628. -- 
  1629. Darin Johnson (...lll-lcc.arpa!leadsv!laic!darin)
  1630.               (...ucbvax!sun!sunncal!leadsv!laic!darin)
  1631.     "All aboard the DOOMED express!"
  1632.